<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns:og="http://ogp.me/ns#">

<head>
	<title>Kafka 中文文档 - ApacheCN</title>
	<link rel='stylesheet' href='./css/styles.css' type='text/css'>
	<link rel='stylesheet' href='./css/syntax-highlighting.css' type='text/css'>
	<link rel="icon" type="image/gif" href="./images/apache_feather.gif">
	<meta name="robots" content="index,follow" />
	<meta name="language" content="en" />
	<meta name="keywords" content="apache kafka messaging queuing distributed stream processing">
	<meta name="description" content="Apache Kafka: A Distributed Streaming Platform.">
	<meta http-equiv='Content-Type' content='text/html;charset=utf-8' />
	<meta name="viewport" content="initial-scale = 1.0,maximum-scale = 1.0" />
	<meta property="og:title" content="Apache Kafka" />
	<meta property="og:image" content="http://apache-kafka.org/images/apache-kafka.png" />
	<meta property="og:description" content="Apache Kafka: A Distributed Streaming Platform." />
	<meta property="og:site_name" content="Apache Kafka" />
	<meta property="og:type" content="website" />
	<link href="https://fonts.googleapis.com/css?family=Cutive+Mono|Roboto:400,700,900" rel="stylesheet">
	<script src="./js/jquery.min.js"></script>
	<script async src="./js/apachecn/googletagmanager.js"></script>
	<script>
		window.dataLayer = window.dataLayer || [];
		function gtag() { dataLayer.push(arguments); }
		gtag('js', new Date());

		gtag('config', 'UA-102475051-9');
	</script>

	<script>
		var _hmt = _hmt || [];
		(function () {
			var hm = document.createElement("script");
			hm.src = "https://hm.baidu.com/hm.js?9f2b74b80ab8aafb5970835acf96a0ea";
			var s = document.getElementsByTagName("script")[0];
			s.parentNode.insertBefore(hm, s);
		})();
	</script>

	<script>
		(function () {
			var bp = document.createElement('script');
			var curProtocol = window.location.protocol.split(':')[0];
			if (curProtocol === 'https') {
				bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
			}
			else {
				bp.src = 'http://push.zhanzhang.baidu.com/push.js';
			}
			var s = document.getElementsByTagName("script")[0];
			s.parentNode.insertBefore(bp, s);
		})();
	</script>
	<script>
		// DO NOT NEED TO UPDATE
		// Legacy versions of the documentation to not do frontend redirect for
		// These docs are written as a single super long file so no need to re-route
		var legacyDocPaths = [
			'./07/documentation',
			'./07/documentation/',
			'./08/documentation',
			'./08/documentation/',
			'./081/documentation',
			'./081/documentation/',
			'./082/documentation',
			'./082/documentation/',
			'./090/documentation',
			'./090/documentation/',
			'./0100/documentation',
			'./0100/documentation/'
		];

		// Any direct request for Streams documentation in docs versions prior to 0101
		// Redirect these requests to the standalone Streams doc page
		var currentPath = window.location.pathname;
		var shouldRedirect = !legacyDocPaths.includes(currentPath);
		var isDocumenationPage = currentPath.includes('/documentation');

		var hasNotSpecifiedFullPath = !currentPath.includes('/documentation/streams') && !currentPath.includes('/documentation/streams/');

		// Look for legacy anchors to clue us in on what full path the user needs
		// Add more as needed
		var specifiedStreamsAnchor = window.location.hash.includes('#streams_');

		if (shouldRedirect && isDocumenationPage && hasNotSpecifiedFullPath) {
			if (specifiedStreamsAnchor) {
				window.location.pathname = currentPath + 'streams';
			}
		}
	</script>
</head>
<!--#include virtual="includes/_header.htm" -->
<body>
	<div class="main">
		<div class="header">
			<a href=""><img width="325" height="97" class="logo" src="images/logo.png"></a>
		</div>

<!--#include virtual="includes/_top.htm" -->
<div class="content">
    <nav class="b-sticky-nav">
  <div class="nav-scroller">
    <div class="nav__inner">
      <a class="b-nav__home nav__item" href="">主页</a>
      <a class="b-nav__intro nav__item" href="intro.html">介绍</a>
      <a class="b-nav__quickstart nav__item" href="quickstart.html">快速开始</a>
      <a class="b-nav__uses nav__item" href="uses.html">使用案例</a>

      <div class="nav__item nav__item__with__subs">
        <a class="b-nav__docs nav__item nav__sub__anchor" href="documentation.html">文档</a>
        <a class="nav__item nav__sub__item" href="documentation.html#gettingStarted">入门</a>
        <a class="nav__item nav__sub__item" href="documentation.html#api">APIs</a>
        <a class="b-nav__streams nav__item nav__sub__item" href="documentation.html#streams">kafka streams</a>
        <a class="nav__item nav__sub__item" href="documentation.html#connect">kafka connect</a>
        <a class="nav__item nav__sub__item" href="documentation.html#configuration">配置</a>
        <a class="nav__item nav__sub__item" href="documentation.html#design">设计</a>
        <a class="nav__item nav__sub__item" href="documentation.html#implementation">实现</a>
        <a class="nav__item nav__sub__item" href="documentation.html#operations">操作</a>
        <a class="nav__item nav__sub__item" href="documentation.html#security">安全</a>
      </div>

      <a class="b-nav__performance nav__item" href="performance.html">性能</a>
      <a class="b-nav__poweredby nav__item" href="powered-by.html">powered by</a>
      <a class="b-nav__project nav__item" href="project.html">项目信息</a>
      <a class="b-nav__ecosystem nav__item" href="https://cwiki.apache.org/confluence/display/KAFKA/Ecosystem" target="_blank">生态圈</a>
      <a class="b-nav__clients nav__item" href="https://cwiki.apache.org/confluence/display/KAFKA/Clients" target="_blank">客户端</a>
      <a class="b-nav__events nav__item" href="events.html">事件</a>
      <a class="b-nav__contact nav__item" href="contact.html">联系我们</a>

      <div class="nav__item nav__item__with__subs">
        <a class="b-nav__apache nav__item nav__sub__anchor b-nav__sub__anchor" href="#">apache</a>
        <a class="b-nav__apache nav__item nav__sub__item" href="http://www.apache.org/" target="_blank">贡献</a>
        <a class="b-nav__apache nav__item nav__sub__item" href="http://www.apache.org/licenses/" target="_blank">license</a>
        <a class="b-nav__apache nav__item nav__sub__item" href="http://www.apache.org/foundation/sponsorship.html" target="_blank">赞助</a>
        <a class="b-nav__apache nav__item nav__sub__item" href="http://www.apache.org/foundation/thanks.html" target="_blank">感谢</a>
        <a class="b-nav__apache nav__item nav__sub__item" href="http://www.apache.org/security/" target="_blank">安全</a>
      </div>

      <a class="btn" href="downloads.html">下载</a>
      <div class="social-links">
        <a class="twitter" href="https://twitter.com/apachekafka" target="_blank">@apachekafka</a>
      </div>
    </div>
  </div>
  <div class="navindicator">
    <div class="b-nav__home navindicator__item"></div>
    <div class="b-nav__intro navindicator__item"></div>
    <div class="b-nav__quickstart navindicator__item"></div>
    <div class="b-nav__uses navindicator__item"></div>
    <div class="b-nav__docs navindicator__item"></div>
    <div class="b-nav__performance navindicator__item"></div>
    <div class="b-nav__poweredby navindicator__item"></div>
    <div class="b-nav__project navindicator__item"></div>
    <div class="b-nav__ecosystem navindicator__item"></div>
    <div class="b-nav__clients navindicator__item"></div>
    <div class="b-nav__events navindicator__item"></div>
    <div class="b-nav__contact navindicator__item"></div>
  </div>
</nav>

		<!--#include virtual="includes/_nav.htm" -->
  <div class="right">
    <h1>Quickstart</h1>
    <!--
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You under the Apache License, Version 2.0
 (the "License"); you may not use this file except in compliance with
 the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-->

<script>
    /*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Define variables for doc templates
var context={
    "version": "10",
    "dotVersion": "1.0",
    "fullDotVersion": "1.0.0",
    "scalaVersion": "2.11"
};

    <!--#include virtual="js/templateData.js" -->
</script>

<script id="quickstart-template" type="text/x-handlebars-template">
    <p>
        本教程假定您是一只小白，没有Kafka 或ZooKeeper 方面的经验。
        Kafka控制脚本在Unix和Windows平台有所不同，在Windows平台，请使用 <code>bin\windows\</code> 而不是<code>bin/</code>, 并将脚本扩展名改为<code>.bat</code>.
    </p>

    <h4><a id="quickstart_download" href="#quickstart_download">Step 1: 下载代码</a></h4>

    <a href="https://www.apache.org/dyn/closer.cgi?path=/kafka/{{fullDotVersion}}/kafka_2.11-{{fullDotVersion}}.tgz" title="Kafka downloads">下载</a>  {{fullDotVersion}}版本并解压缩。.

    <pre class="brush: bash;">
&gt; tar -xzf kafka_2.11-{{fullDotVersion}}.tgz
&gt; cd kafka_2.11-{{fullDotVersion}}
</pre>

    <h4><a id="quickstart_startserver" href="#quickstart_startserver">Step 2: 启动服务器</a></h4>

    <p>
        Kafka 使用 <a href="https://zookeeper.apache.org/">ZooKeeper</a> 如果你还没有ZooKeeper服务器，你需要先启动一个ZooKeeper服务器。 您可以通过与kafka打包在一起的便捷脚本来快速简单地创建一个单节点ZooKeeper实例。

    <pre class="brush: bash;">
&gt; bin/zookeeper-server-start.sh config/zookeeper.properties
[2013-04-22 15:01:37,495] INFO Reading configuration from: config/zookeeper.properties (org.apache.zookeeper.server.quorum.QuorumPeerConfig)
...
</pre>

    <p>现在启动Kafka服务器：</p>
    <pre class="brush: bash;">
&gt; bin/kafka-server-start.sh config/server.properties
[2013-04-22 15:01:47,028] INFO Verifying properties (kafka.utils.VerifiableProperties)
[2013-04-22 15:01:47,051] INFO Property socket.send.buffer.bytes is overridden to 1048576 (kafka.utils.VerifiableProperties)
...
</pre>

    <h4><a id="quickstart_createtopic" href="#quickstart_createtopic">Step 3: 创建一个 topic</a></h4>

    <p>让我们创建一个名为“test”的topic，它有一个分区和一个副本：</p>
    <pre class="brush: bash;">
&gt; bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
</pre>

    <p>现在我们可以运行list（列表）命令来查看这个topic：</p>
    <pre class="brush: bash;">
&gt; bin/kafka-topics.sh --list --zookeeper localhost:2181
test
</pre>
    <p>或者，您也可将代理配置为：在发布的topic不存在时，自动创建topic，而不是手动创建。</p>

    <h4><a id="quickstart_send" href="#quickstart_send">Step 4: 发送一些消息</a></h4>

    <p>Kafka自带一个命令行客户端，它从文件或标准输入中获取输入，并将其作为message（消息）发送到Kafka集群。默认情况下，每行将作为单独的message发送。</p>
    <p>
        运行 producer，然后在控制台输入一些消息以发送到服务器。</p>

    <pre class="brush: bash;">
&gt; bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test
This is a message
This is another message
</pre>

    <h4><a id="quickstart_consume" href="#quickstart_consume">Step 5: 启动一个 consumer</a></h4>

    <p>Kafka 还有一个命令行consumer（消费者），将消息转储到标准输出。</p>

    <pre class="brush: bash;">
&gt; bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning
This is a message
This is another message
</pre>
    <p>
        如果您将上述命令在不同的终端中运行，那么现在就可以将消息输入到生产者终端中，并将它们在消费终端中显示出来。
    <p>
        所有的命令行工具都有其他选项；运行不带任何参数的命令将显示更加详细的使用信息。
    </p>

    <h4><a id="quickstart_multibroker" href="#quickstart_multibroker">Step 6: 设置多代理集群</a></h4>

    <p>到目前为止，我们一直在使用单个代理，这并不好玩。对 Kafka来说，单个代理只是一个大小为一的集群，除了启动更多的代理实例外，没有什么变化。
        为了深入了解它，让我们把集群扩展到三个节点（仍然在本地机器上）。</p>
    <p>
        首先，为每个代理创建一个配置文件 (在Windows上使用<code>copy</code> 命令来代替)：
    </p>
    <pre class="brush: bash;">
&gt; cp config/server.properties config/server-1.properties
&gt; cp config/server.properties config/server-2.properties
</pre>

    <p>
        现在编辑这些新文件并设置如下属性：
    </p>
    <pre class="brush: text;">

config/server-1.properties:
    broker.id=1
    listeners=PLAINTEXT://:9093
    log.dir=/tmp/kafka-logs-1

config/server-2.properties:
    broker.id=2
    listeners=PLAINTEXT://:9094
    log.dir=/tmp/kafka-logs-2
</pre>
    <p><code>broker.id</code>属性是集群中每个节点的名称，这一名称是唯一且永久的。我们必须重写端口和日志目录，因为我们在同一台机器上运行这些，我们不希望所有的代理尝试在同一个端口注册，或者覆盖彼此的数据。</p>
    <p>
        我们已经建立Zookeeper和一个单节点了，现在我们只需要启动两个新的节点：
    </p>
    <pre class="brush: bash;">
&gt; bin/kafka-server-start.sh config/server-1.properties &amp;
...
&gt; bin/kafka-server-start.sh config/server-2.properties &amp;
...
</pre>

    <p>现在创建一个副本为3的新topic：</p>
    <pre class="brush: bash;">
&gt; bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 3 --partitions 1 --topic my-replicated-topic
</pre>

    <p>Good，现在我们有一个集群，但是我们怎么才能知道那些代理在做什么呢？运行"describe topics"命令来查看：</p>
    <pre class="brush: bash;">
&gt; bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic my-replicated-topic
Topic:my-replicated-topic	PartitionCount:1	ReplicationFactor:3	Configs:
	Topic: my-replicated-topic	Partition: 0	Leader: 1	Replicas: 1,2,0	Isr: 1,2,0
</pre>
    <p>以下是对输出信息的解释。第一行给出了所有分区的摘要，下面的每行都给出了一个分区的信息。因为我们只有一个分区，所以只有一行。</p>
    <ul>
        <li>“leader”是负责给定分区所有读写操作的节点。每个节点都是随机选择的部分分区的领导者。
        <li>“replicas”是复制分区日志的节点列表，不管这些节点是leader还是仅仅活着。
        <li>“isr”是一组“同步”replicas，是replicas列表的子集，它活着并被指到leader。
    </ul>
    <p>请注意，在示例中，节点1是该主题中唯一分区的领导者。</p>
    <p>
        我们可以在已创建的原始主题上运行相同的命令来查看它的位置：
    </p>
    <pre class="brush: bash;">
&gt; bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic test
Topic:test	PartitionCount:1	ReplicationFactor:1	Configs:
	Topic: test	Partition: 0	Leader: 0	Replicas: 0	Isr: 0
</pre>
    <p>这没什么大不了，原来的主题没有副本且在服务器0上。我们创建集群时，这是唯一的服务器。</p>
    <p>
        让我们发表一些信息给我们的新topic：
    </p>
    <pre class="brush: bash;">
&gt; bin/kafka-console-producer.sh --broker-list localhost:9092 --topic my-replicated-topic
...
my test message 1
my test message 2
^C
</pre>
    <p>现在我们来消费这些消息：</p>
    <pre class="brush: bash;">
&gt; bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic my-replicated-topic
...
my test message 1
my test message 2
^C
</pre>

    <p>让我们来测试一下容错性。 Broker 1 现在是 leader，让我们来杀了它：</p>
    <pre class="brush: bash;">
&gt; ps aux | grep server-1.properties
7564 ttys002    0:15.91 /System/Library/Frameworks/JavaVM.framework/Versions/1.8/Home/bin/java...
&gt; kill -9 7564
</pre>

    在 Windows 上用:
    <pre class="brush: bash;">
&gt; wmic process where "caption = 'java.exe' and commandline like '%server-1.properties%'" get processid
ProcessId
6016
&gt; taskkill /pid 6016 /f
</pre>

    <p>领导权已经切换到一个从属节点，而且节点1也不在同步副本集中了：</p>

    <pre class="brush: bash;">
&gt; bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic my-replicated-topic
Topic:my-replicated-topic	PartitionCount:1	ReplicationFactor:3	Configs:
	Topic: my-replicated-topic	Partition: 0	Leader: 2	Replicas: 1,2,0	Isr: 2,0
</pre>
    <p>不过，即便原先写入消息的leader已经不在，这些消息仍可用于消费：</p>
    <pre class="brush: bash;">
&gt; bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic my-replicated-topic
...
my test message 1
my test message 2
^C
</pre>


    <h4><a id="quickstart_kafkaconnect" href="#quickstart_kafkaconnect">Step 7: 使用Kafka Connect来导入/导出数据</a></h4>

    <p>从控制台读出数据并将其写回是十分方便操作的，但你可能需要使用其他来源的数据或将数据从Kafka导出到其他系统。针对这些系统，
        你可以使用Kafka Connect来导入或导出数据，而不是写自定义的集成代码。</p>

    <p>Kafka Connect是Kafka的一个工具，它可以将数据导入和导出到Kafka。它是一种可扩展工具，通过运行<i>connectors（连接器）</i>，
        使用自定义逻辑来实现与外部系统的交互。 在本文中，我们将看到如何使用简单的connectors来运行Kafka Connect，这些connectors
        将文件中的数据导入到Kafka topic中，并从中导出数据到一个文件。</p>

    <p>首先，我们将创建一些种子数据来进行测试：</p>

    <pre class="brush: bash;">
&gt; echo -e "foo\nbar" > test.txt
</pre>
    在Windows系统使用:
    <pre class="brush: bash;">
&gt; echo foo> test.txt
&gt; echo bar>> test.txt
</pre>

    <p>接下来，我们将启动两个<i>standalone（独立）</i>运行的连接器，这意味着它们各自运行在一个单独的本地专用
        进程上。 我们提供三个配置文件。首先是Kafka Connect的配置文件，包含常用的配置，如Kafka brokers连接方式和数据的序列化格式。
        其余的配置文件均指定一个要创建的连接器。这些文件包括连接器的唯一名称，类的实例，以及其他连接器所需的配置。</p>

    <pre class="brush: bash;">
&gt; bin/connect-standalone.sh config/connect-standalone.properties config/connect-file-source.properties config/connect-file-sink.properties
</pre>

    <p>这些包含在Kafka中的示例配置文件使用您之前启动的默认本地群集配置，并创建两个连接器：
        第一个是源连接器，用于从输入文件读取行，并将其输入到 Kafka topic。
        第二个是接收器连接器，它从Kafka topic中读取消息，并在输出文件中生成一行。</p>

    <p>
        在启动过程中，你会看到一些日志消息，包括一些连接器正在实例化的指示。
        一旦Kafka Connect进程启动，源连接器就开始从<code> test.txt </code>读取行并且
        将它们生产到主题<code> connect-test </code>中，同时接收器连接器也开始从主题<code> connect-test </code>中读取消息，
        并将它们写入文件<code> test.sink.txt </code>中。我们可以通过检查输出文件的内容来验证数据是否已通过整个pipeline进行交付：
    </p>


    <pre class="brush: bash;">
&gt; more test.sink.txt
foo
bar
</pre>

    <p>
        请注意，数据存储在Kafka topic<code> connect-test </code>中，因此我们也可以运行一个console consumer（控制台消费者）来查看
        topic 中的数据（或使用custom consumer（自定义消费者）代码进行处理）：
    </p>


    <pre class="brush: bash;">
&gt; bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic connect-test --from-beginning
{"schema":{"type":"string","optional":false},"payload":"foo"}
{"schema":{"type":"string","optional":false},"payload":"bar"}
...
</pre>

    <p>连接器一直在处理数据，所以我们可以将数据添加到文件中，并看到它在pipeline 中移动：</p>

    <pre class="brush: bash;">
&gt; echo Another line>> test.txt
</pre>

    <p>您应该可以看到这一行出现在控制台用户输出和接收器文件中。</p>

    <h4><a id="quickstart_kafkastreams" href="#quickstart_kafkastreams">Step 8:使用 Kafka Streams 来处理数据</a></h4>

    <p>
        Kafka Streams是用于构建实时关键应用程序和微服务的客户端库，输入与输出数据存储在Kafka集群中。
        Kafka Streams把客户端能够轻便地编写部署标准Java和Scala应用程序的优势与Kafka服务器端集群技术相结合，使这些应用程序具有高度伸缩性、弹性、容错性、分布式等特性。
        本<a href="{{version}}/documentation/streams/quickstart">快速入门示例</a>将演示如何运行一个基于该库编程的流式应用程序。
    </p>


</script>

<div class="p-quickstart"></div>
    <!--#include virtual="10/quickstart.html" -->
    				</div>
			</div>
		</div>
		<div class="footer">
			<div class="footer__inner">
				<div class="footer__legal">
					<span class="footer__legal__one">The contents of this website are &copy; 2016 <a href="https://www.apache.org/" target="_blank">Apache Software Foundation</a> under the terms of the <a href="https://www.apache.org/licenses/LICENSE-2.0.html" target="_blank">Apache License v2</a>.</span>
					<span class="footer__legal__two">Apache Kafka, Kafka, and the Kafka logo are either registered trademarks or trademarks of The Apache Software Foundation</span>
					<span class="footer__legal__three">in the United States and other countries.</span>
				</div>
				<a class="apache-feather" target="_blank" href="http://www.apache.org">
					<img width="40" src="images/feather-small.png" alt="Apache Feather">
				</a>
			</div>
		</div>
	</body>

    <script type="text/javascript" src="js/syntaxhighlighter.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0/handlebars.js"></script>
	<script>
		$(function () {
			// list of pages that are rendered with Handlebars
			var templates = [
				'introduction',
				'implementation',
				'design',
				'api',
				'configuration',
				'ops',
				'security',
				'connect',
				'streams',
				'quickstart',
				'toc',
				'upgrade',
				'content'
			];

			// loop through all Handlebar templates on the page and render them
			for(var i = 0; i < templates.length; i++) {
				var templateScript = $("#" + templates[i] + "-template").html();
				if(templateScript) {
					var template = Handlebars.compile(templateScript);
					var html = template(context);
					$(".p-" + templates[i]).html(html);
				}
			}
		});
	</script>

	<script src="js/jquery.sticky-kit.min.js"></script>
	<script>
		$(function() {
			// Set mobile scroll position on nav
			function setNavScroll(offsetLeft) {
				$('.nav-scroller').animate({
					scrollLeft: $('.nav-scroller').scrollLeft() + $('nav .selected').offset().left - offsetLeft
				}, 50);
			}

			// Helper classes for nav
			$('nav').mouseenter(function(){
				$(this).addClass('hovering');
			});
			$('nav').mouseleave(function(){
				$(this).removeClass('hovering');
			});

			// Handle expanding sections of nav (async)
			$('.b-nav__sub__anchor').click(function(){
				$('nav .selected').removeClass('selected');
				$('.nav__item__with__subs--expanded').removeClass('nav__item__with__subs--expanded');

				$(this).addClass('selected');
				$(this).parent().toggleClass('nav__item__with__subs--expanded');

				if($(window).width() <= 650) {
					window.setTimeout(function(){
						setNavScroll(30);
					}, 300);
				}
			});

			// Initialize sticky elements on the page
			if($(window).width() > 650) {
				// Nav for desktop
				$('.b-sticky-nav').stick_in_parent({offset_top: 40});
				// Documentation banner for desktop
				$('.b-sticky-doc-banner').stick_in_parent({offset_top: 0});
			}	else {
				// Scroll nav for mobile so current nav item is in view
				window.setTimeout(function(){
					setNavScroll(80);
				}, 300);
			}

			// On window resize check to see if stuff should be unstuck
			window.onresize = function(event) {
			  if($(window).width() <= 650) {
			    $('.b-sticky-nav').trigger("sticky_kit:detach");
			  } else {
			    $('.b-sticky-nav').stick_in_parent({offset_top: 40});
					$('.b-sticky-doc-banner').stick_in_parent({offset_top: 0});
			  }
			};
		});
	</script>


</html>

		<!--#include virtual="includes/_footer.htm" -->
<script>
// Show selected style on nav item
$(function() { $('.b-nav__quickstart').addClass('selected'); });
</script>
